<?php
/**
 * User: Mykola B.
 * Date: 3/2/13
 * Time: 11:48 AM
 */
namespace controllers {
    class DefaultController
    {
        private $userController;

        public function homeGet($f3) {
            if ($f3->get('is_authenticated')) {
                $this->setCars($f3);
                $this->setDatetimes($f3);
                $f3->set('isPost', false);
                $template = new \Template();
                echo $template->render('home.html');
            } else {
                $f3->reroute('/login?url='.$f3->get('SERVER.REQUEST_URI'));
            }
        }

        public function homePost($f3) {
            if ($f3->get('is_authenticated')) {
                $car = $f3->get('POST.car');
                $startTime = $f3->get('POST.start_time');
                $endTime = $f3->get('POST.end_time');

                $this->writeCarStops($f3, $car, $startTime, $endTime);

                $f3->set('isPost', true);
                $f3->set('carId', $car);
                $f3->set('startTime', $startTime);
                $f3->set('endTime', $endTime);
                $f3->set('has_google_map', true); // flag for script inclusion
                $this->setCars($f3);
                $this->setDatetimes($f3);
                $this->setVisualParams($f3);
                $template = new \Template();
                echo $template->render('home.html');
            } else {
                $f3->reroute('/login?url='.$f3->get('SERVER.REQUEST_URI'));
            }
        }

        private function setCars($f3) {
            $car = new \models\CarModel($f3);
            $f3->set('cars', $car->all());
        }

        private function setDatetimes($f3) {
            $db = \DataBase::getConnection();
            $f3->set('datetimes', $db->exec('SELECT DISTINCT time FROM car_positions;'));
        }

        private function writeCarStops($f3, $car, $startTime, $endTime) {
            $carPosition = new \models\CarPositionsModel($f3);
            $carPositions = $carPosition->find(
                array('car_id=? AND time > ? AND time < ?', $car, $startTime, $endTime),
                array('order' => 'id')
            );

            $vParam = new \models\VisualisationParamsModel();
            // get clustering parameters
            $vParam->getByKey('radius');
            $radius = intval($vParam->value);
            $vParam->getByKey('locationsThreshold');
            $locThresh = intval($vParam->value);
            // stop length limit in seconds
            $vParam->getByKey('stopLengthLimit');
            $stopLengthLimit = new \Time($vParam->value);

            $points = new \geo\PointCollection($carPositions);
            $clusters = new \geo\ClusterCollection($points, $radius, $locThresh);

            $carStops = array();
            $minLength = +INF;
            $maxLength = 0;
            foreach ($clusters as $cluster) {
                $carStop = array();
                $last = $cluster->last();
                $first = $cluster->first();
                $carStop[':car_id'] = $first->get('car_id');
                $carStop[':latitude'] = $first->latitude;
                $carStop[':longitude'] = $first->longitude;
                $carStop[':time'] = $first->get('time');

                $stopEnd = new \DateTime($last->get('time'));
                $stopStart = new \DateTime($first->get('time'));
                $length = \Time::fromSeconds($stopEnd->getTimestamp() - $stopStart->getTimestamp());

                $carStop[':length'] = (string) $length;
                $carStop[':status'] = $length->lt($stopLengthLimit) ? 1 : 0;
                \DataBase::getConnection()->exec(
                    array(
                        sprintf('INSERT INTO %s (car_id, latitude, longitude, `time`, `length`, `status`) VALUES (:car_id, :latitude, :longitude, :time, :length, :status);', $f3->get('SETTINGS')->table_names->table3)
                    ),
                    array(
                        $carStop
                    )
                );
                // remove the : from the beginning of each key
                // find maximum and minimum stop length
                // convert length to seconds
                foreach ($carStop as $key => $value) {
                    if ($key == ':length') {
                        // convert length to seconds
                        $value = new \Time($value);
                        $value = $value->seconds;
                        // find min and max stop length
                        if ($value < $minLength) $minLength = $value;
                        if ($value > $maxLength) $maxLength = $value;
                    }
                    $carStop[substr($key, 1)] = $value;
                    unset($carStop[$key]);
                }
                // add address
                if ($carStop['status'] == 0) {
                    $carStop['address'] = $this->getAddress($carStop['latitude'], $carStop['longitude']);
                }
                array_push($carStops, $carStop);
            }
            $f3->set('car_stops', $carStops);
            $f3->set('min_stop_length', $minLength);
            $f3->set('max_stop_length', $maxLength);
        }

        private function setVisualParams($f3) {
            $vParam = new \models\VisualisationParamsModel();
            $vParam->getByKey('opacity');
            $f3->set('opacity', $vParam->value);
            $vParam->getByKey('color1');
            $f3->set('color1', $vParam->value);
            $vParam->getByKey('color2');
            $f3->set('color2', $vParam->value);
            $vParam->getByKey('minSymbolRadius');
            $f3->set('minSymbolRadius', intval($vParam->value));
            $vParam->getByKey('maxSymbolRadius');
            $f3->set('maxSymbolRadius', intval($vParam->value));
            $vParam->getByKey('mapHeight');
            $f3->set('mapHeight', $vParam->value);
            $vParam->getByKey('mapWidth');
            $f3->set('mapWidth', $vParam->value);
        }

        private function getAddress($latitude, $longitude) {
            $data = array('sensor' => 'false', 'latlng' => $latitude . ',' . $longitude);
            $options = array(
                'http' => array(
                    'method' => 'GET'
                )
            );
            $context = stream_context_create($options);
            $response = file_get_contents(
                'http://maps.googleapis.com/maps/api/geocode/json?' . http_build_query($data), false, $context
            );
            $response = json_decode($response);
            if (isset($response->results[0]->formatted_address)) {
                return $response->results[0]->formatted_address;
            }
            return null;
        }
    }
}